using System;
using System.Collections.Generic;
using System.Text;
using System.Xml.Serialization;
using System.Xml;

namespace PDOGenerator.Util
{
    public class SerialDictionary<K, V> : SortedDictionary<K, V>, IXmlSerializable
    {
        #region IXmlSerializable Members
        public System.Xml.Schema.XmlSchema GetSchema()
        {
            return null;
        }

        public void ReadXml(XmlReader reader)
        {
            XmlSerializer keySer = new XmlSerializer(typeof(K));
            XmlSerializer valueSer = new XmlSerializer(typeof(V));

            // there seems to be a bug in the deserializer which means that we are one tag too high!
            string ElementName = reader.Name;

            if (ElementName != "dictionary")
            {
                reader.ReadStartElement(ElementName);
            }

            reader.ReadStartElement("dictionary");
            while (reader.NodeType != XmlNodeType.EndElement)
            {
                reader.ReadStartElement("item");

                reader.ReadStartElement("key");
                object key = keySer.Deserialize(reader);
                reader.ReadEndElement();

                reader.ReadStartElement("value");
                object value = valueSer.Deserialize(reader);
                reader.ReadEndElement();

                Add((K)key, (V)value);

                reader.ReadEndElement();
                reader.MoveToContent();
            }

            // need to check this for an empty dictionary
            while (reader.Name == "dictionary" || reader.Name == ElementName)
            {
                reader.ReadEndElement();
            }
        }

        public void WriteXml(XmlWriter writer)
        {
            XmlSerializer keySer = new XmlSerializer(typeof(K));
            XmlSerializer valueSer = new XmlSerializer(typeof(V));

            writer.WriteStartElement("dictionary");
            foreach (K key in Keys)
            {
                writer.WriteStartElement("item");

                writer.WriteStartElement("key");
                keySer.Serialize(writer, key);
                writer.WriteEndElement();

                writer.WriteStartElement("value");
                V value = this[key];
                valueSer.Serialize(writer, value);
                writer.WriteEndElement();

                writer.WriteEndElement();
            }
            writer.WriteEndElement();
        }

        #endregion
    }
}
